#
# CONVENTIONS
#	place newer tests first (ensures they fail quicker if they fail, and that they clean-up after themselves so the remaining tests can run)
#
# REQUIRED FILES (not provided, should be in same directory as this)
# 	account1.txt
#		single line of text - the account name to sign into ICHC with, followed by the password, separated by :
#      (please start account name with "selenium"  (example "selenium_m0nk_3y:mysecretpassword")
#	account2.txt	
#		single line of text - the account name to sign into ICHC with, followed by the password, separated by :
#      (please start account name with "selenium"  (example "selenium_m0nk_3y:mysecretpassword")
#		this account is used to send offline messages to
#
#

require 'rubygems'
require 'selenium-webdriver'
#require 'test/unit'  #hmm, would be handy to use:)

def text_from_file(filename)
	File.open(filename, 'r') { |f| f.read }
end
	
def sign_into_site(server, driver, file)
	driver.get server
	# sleep(1)
	driver.find_element(:link, "Sign-in").click
	begin
		account_name_field = driver.find_element :name => "txtAccountName"
	rescue
		print "didn't find accountname for signing in, giving it an extra 5 seconds\n"
		sleep 5
		account_name_field = driver.find_element :name => "txtAccountName"
	end
	account = text_from_file(file)
	account_name_field.send_keys account.split(":")[0]
	account_password_field = driver.find_element :name => "txtPassword1"
	account_password_field.send_keys account.split(":")[1]
	signin_button = driver.find_element :id => "btnSubmit"
	signin_button.click
end
	
def sign_out_of_site(server, driver)
	wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
	element = wait.until { driver.find_element(:link_text => "signout") }
	element.click
end

def get_pop_up_window(driver)
	begin
		alert = driver.switch_to.alert
	rescue
		sleep 2
		begin
			alert = driver.switch_to.alert
		rescue
			sleep 2
			alert = driver.switch_to.alert
		end
	end
	alert
end
	
def send_message(server, driver, account, message)
	wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
	acc = text_from_file(account).split(":")[0]
	driver.get server + "/user/" + acc

	#this sucks, there must be a better way to work around these lameass generated id's
	send_message_btn = wait.until { driver.find_element :id => "ctl00_ContentPlaceHolder1_btnSendMessage" }
	send_message_btn.click

	element = wait.until { driver.find_element :id => "ctl00_ContentPlaceHolder1_txtNewMessage" }
	element.send_keys message

	send_message_btn = wait.until { driver.find_element :id => "ctl00_ContentPlaceHolder1_btnSendMessage" }
	send_message_btn.click

	wait.until { driver.title.downcase.start_with? "messages" }
end
	
def check_message_thread(server, driver, account, message)
	acc = text_from_file(account).split(":")[0]
	wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
	wait.until { driver.title.downcase.start_with? "icanhazchat" }

	# do we have unread messages? BUGGY, DOESNT ALWAYS EXIST!
	begin
		element = driver.find_element :id => "unread_mess"
	rescue
		log_error("no unread messages")
	end
	
	element = wait.until { driver.find_element(:link_text => "messages") }
	
	element.click	
	
	driver.execute_script("open_message('" + acc + "')")
	wait.until { driver.title.downcase.start_with? acc }

	if (!driver.page_source.include?(message)) 
		log_error("message not delivered")
	end
end	
	
	
def delete_message_thread(server, driver, account)
	wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
	acc = text_from_file(account).split(":")[0]
	driver.get server + "/messages/" + acc
	
	#tried to use alt-x before, but then switching to alert fails. 
	element = wait.until { driver.find_element(:id => "ctl00_ContentPlaceHolder1_btnDeleteThread") }
	element.click()
	alert = get_pop_up_window(driver)
	if !alert.text.include?("Delete this message thread?") then
		log_error("Pop up alert when deleting messages contained unexpected text [" + alert.text + "]")
	end
	alert.accept
end
	
def test_offline_messaging(server, driver, account1, account2)
	message_text = "random text " + Random.rand(10000).to_s()

	# send message from account1 -> account2
	print "\nsend message from account1 -> account2\n"
	sign_into_site(server, driver, account1)
	send_message(server, driver, account2, message_text)
	sign_out_of_site(server,driver)

	#sign into site as account2, do not check unread messages
	print "sign into site as account2, do not check unread messages\n"
	sign_into_site(server, driver, account2)
	sign_out_of_site(server,driver)

	# send another message from account1 -> account2
	print "send another message from account1 -> account2\n"
	sign_into_site(server, driver, account1)
	send_message(server, driver, account2, message_text)
	sign_out_of_site(server,driver)
	
	#check if new messages?
	print "check if new messages?\n"
	sign_into_site(server, driver, account2)
	check_message_thread(server, driver, account1, message_text)
	delete_message_thread(server, driver, account1)
end
	
def log_error(msg)
	@error_log << msg
	print "	*** error: " + msg + "\n"
	# raise msg
	sleep(10)
end
	
#drivers_to_use = Array['chrome', 'firefox', 'ie']
#drivers_to_use = Array['chrome', 'ie']
drivers_to_use = Array['chrome','firefox']
#drivers_to_use = Array['ie', 'chrome','firefox']
#drivers_to_use = Array['opera']

#drivers_to_use = Array['chrome']
#drivers_to_use = Array['firefox']
#drivers_to_use = Array['ie']

#print "defining"
#tests_to_run = Array[test_chat_basic, test_textonly, test_xss]
#print "done defining"

@error_log = []
server = text_from_file("server_to_test.txt")

drivers_to_use.each { |driver_name|
	# set_configuration( "localhost", driver );
	
	case driver_name
		when "chrome"
			driver = Selenium::WebDriver.for :chrome
		when "ie"
			driver = Selenium::WebDriver.for :ie
		when "opera"
			driver = Selenium::WebDriver.for :opera
		else
			driver = Selenium::WebDriver.for :firefox
	end

	account1 = "account1.txt"
	account2 = "account2.txt"

	test_offline_messaging(server, driver, account1, account2)

	print "Errors found: " + @error_log.size().to_s + "\n"
	@error_log.each { |msg|
		print "FOUND ERROR: " + msg + "\n"
	}

	# chromedriver.exe sometimes crashes here - their bug?
	driver.quit
}

